package cn.com.zt.activity.scan

import android.content.Context
import android.graphics.Rect
import android.graphics.RectF
import android.util.AttributeSet
import android.util.Log
import android.widget.FrameLayout
import androidx.camera.core.CameraSelector
import androidx.camera.core.ImageCapture
import androidx.camera.core.TorchState
import androidx.camera.view.LifecycleCameraController
import androidx.camera.view.PreviewView
import androidx.lifecycle.LifecycleOwner
import cn.com.zt.listener.QRCodeAnalyser
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors

/**
 * 使用cameraX扫码后处理的view,需要结合谷歌的mlkit（需要导入）
 */
class CameraXScanView(context: Context, attr: AttributeSet) :
    FrameLayout(context, attr) {
    private var scannerView: ScannerView
    private var previewView: PreviewView
    private var cameraExecutor: ExecutorService
    private var lifecycleCameraController: LifecycleCameraController
    private var listener: OnResultAndFlashListener? = null
    private var scaleX = 0f
    private var scaleY = 0f

    private fun translateX(x: Float): Float = x * scaleX
    private fun translateY(y: Float): Float = y * scaleY

    init {
        cameraExecutor = Executors.newSingleThreadExecutor()
        previewView = PreviewView(context)
        scannerView = ScannerView(context)
        val param = FrameLayout.LayoutParams(
            LayoutParams.MATCH_PARENT,
            LayoutParams.MATCH_PARENT
        )
        SoundPoolUtil.instance.loadQrcodeCompletedWav(context)//初始化扫码语音播放beep
        lifecycleCameraController = LifecycleCameraController(context)
        lifecycleCameraController.cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA//默认后摄像头
        lifecycleCameraController.imageCaptureFlashMode = ImageCapture.FLASH_MODE_AUTO
        previewView.controller = lifecycleCameraController
        addView(previewView, param)
        addView(scannerView, param)
    }

    /**
     * 一定要执行绑定，否则无效
     * onFlashLightStatusCallback:闪光灯开启与否的状态
     */
    fun bindToLifecycle(
        lifecycleOwner: LifecycleOwner,
        outListener: OnResultAndFlashListener,
    ) {
        this.listener = outListener
        lifecycleCameraController.bindToLifecycle(lifecycleOwner)
        lifecycleCameraController.cameraInfo?.torchState?.observe(lifecycleOwner) {
            if (it == TorchState.OFF) {
                listener?.onFlashLightStatusCallback(false)
            } else {
                listener?.onFlashLightStatusCallback(true)
            }
        }
        startOneScan()//开启单次扫描
    }

    /**
     * 开始支持单次扫描
     * 重复扫描调用这个即可
     */
    fun startOneScan() {
        lifecycleCameraController.setImageAnalysisAnalyzer(
            cameraExecutor, createQrCodeAnalyser()
        )
    }

    /**
     * 构建一个可单次返回扫描结果的实例
     */
    private fun createQrCodeAnalyser(): QRCodeAnalyser {
        return QRCodeAnalyser { barcodes, imageWidth, imageHeight ->
            if (barcodes.isEmpty()) {
                return@QRCodeAnalyser
            }
            SoundPoolUtil.instance.playQrcodeCompleted()//播放
            val list = ArrayList<RectF>()
            val strList = ArrayList<String>()

            barcodes.forEach { barcode ->
                barcode.boundingBox?.let { rect ->
                    val translateRect = translateRect(rect)
                    list.add(translateRect)
                    Log.e(
                        "ztzt", "left：${translateRect.left}  +" +
                                "  top：${translateRect.top}  +  right：${translateRect.right}" +
                                "  +  bottom：${translateRect.bottom}"
                    )
                    Log.e("ztzt", "barcode.rawValue：${barcode.rawValue}")
                    strList.add(barcode.rawValue ?: "No Value")
                }
            }
            judgeIntent(strList)
        }
    }


    /**
     * 开启闪光灯
     */
    fun startFlashLight(open: Boolean) {
        lifecycleCameraController.enableTorch(open)
    }

    private fun judgeIntent(list: ArrayList<String>) {
        val sb = StringBuilder()
        list.forEach {
            sb.append(it)
            sb.append("\n")
        }
        intentToResult(sb.toString())
    }

    private fun intentToResult(result: String) {
        listener?.onResult(result)
    }

    //将扫描的矩形换算为当前屏幕大小
    private fun translateRect(rect: Rect) = RectF(
        translateX(rect.left.toFloat()),
        translateY(rect.top.toFloat()),
        translateX(rect.right.toFloat()),
        translateY(rect.bottom.toFloat())
    )


    override fun onDetachedFromWindow() {
        super.onDetachedFromWindow()
        cameraExecutor.shutdown()
        lifecycleCameraController.unbind()
    }

    interface OnResultAndFlashListener {
        fun onResult(result: String)
        fun onFlashLightStatusCallback(isOpen: Boolean)
    }

}